﻿using System.Reflection;
using KinonekoSoftware.CodariaDB.Languages;

namespace KinonekoSoftware.CodariaDB.Presets
{
    public static class PresetManager
    {
        internal const string FileName_Prefix = "KinonekoSoftware.CodariaDB.Presets.";
        internal static readonly string[] FileName_Avatar = new[]
        {
            "avatar_1.png", "avatar_2.png", "avatar_3.png", "avatar_4.png",
        };
        internal static readonly string[] FileName_Icon = new[]
        {
            "icon_1.png", "icon_2.png", "icon_3.png", "icon_4.png", "icon_5.png", "icon_6.png", "icon_7.png", "icon_8.png", "icon_9.png", "icon_10.png", "icon_11.png", "icon_12.png",
        };

        internal static async Task<Result<byte[]>> ExtractResourceToBufferAsync(Assembly assembly, string fileName)
        {
            if (assembly is null ||
                string.IsNullOrEmpty(fileName))
            {
                return Result<byte[]>.Failed(string.Empty);
            }


            var stream = assembly.GetManifestResourceStream(fileName);

            if (stream is null)
            {
                return Result<byte[]>.Failed(string.Empty);
            }

            var buffer = new byte[(int)stream.Length];
            var result = await stream.ReadAsync(buffer);

            if (result != buffer.Length)
            {
                return Result<byte[]>.Failed(string.Empty);
            }

            return Result<byte[]>.Success(buffer);
        }

        internal static Result<byte[]> ExtractResourceToBuffer(Assembly assembly, string fileName)
        {
            if (assembly is null ||
                string.IsNullOrEmpty(fileName))
            {
                return Result<byte[]>.Failed(string.Empty);
            }


            var stream = assembly.GetManifestResourceStream(fileName);

            if (stream is null)
            {
                return Result<byte[]>.Failed(string.Empty);
            }

            var buffer = new byte[(int)stream.Length];
            var result = stream.Read(buffer);

            if (result != buffer.Length)
            {
                return Result<byte[]>.Failed(string.Empty);
            }

            return Result<byte[]>.Success(buffer);
        }

        internal static async Task ExtractResourceToDirectory(Assembly assembly, string fileName, string outputFileName)
        {
            var r = await ExtractResourceToBufferAsync(assembly, fileName);

            if (!r.IsFinished)
            {
                return;
            }

            await File.WriteAllBytesAsync(outputFileName, r.Value);
        }

        public static async Task ExtractResources(string workspace, Action<string> progressCallback)
        {
            var presets    = _File.GetDir(null, Path.Combine(workspace, "Presets"));
            var avatarPath = Path.Combine(presets, "avatar.png");
            var iconPath   = Path.Combine(presets, "icon.png");
            var assembly   = typeof(PresetManager).Assembly;

            progressCallback?.Invoke(CodariaSR.Text_ExtractPresets_Avatar);
            await ExtractResourceToDirectory(assembly, $"{FileName_Prefix}{FileName_Avatar[3]}", avatarPath);

            progressCallback?.Invoke(CodariaSR.Text_ExtractPresets_Icon);
            await ExtractResourceToDirectory(assembly, $"{FileName_Prefix}{FileName_Icon[4]}", iconPath);
        }

        public static async Task OverrideIcon(string   workspace, byte[] buffer) => await IconSystem.OverrideIcon(workspace, buffer);
        public static async Task OverrideAvatar(string workspace, byte[] buffer) => await GravatarSystem.OverrideAvatar(workspace, buffer);
    }
}